package com.vf.cloud.common.util;

import java.sql.Connection;
import java.util.LinkedList;
import java.util.List;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import com.jfinal.kit.StrKit;
import com.jfinal.plugin.activerecord.ActiveRecordPlugin;
import com.jfinal.plugin.activerecord.dialect.MysqlDialect;
import com.jfinal.plugin.activerecord.dialect.OracleDialect;
import com.jfinal.plugin.activerecord.dialect.PostgreSqlDialect;
import com.jfinal.plugin.activerecord.dialect.SqlServerDialect;
import com.jfinal.plugin.activerecord.dialect.Sqlite3Dialect;
import com.jfinal.plugin.druid.DruidPlugin;
import com.vf.cloud.common.datasource.domain.Database;

public class DbUtil {
	
	public static void init() {
		init(parseXmlToList());
	}
	
	private static void init(List<Database> databases) {
		DruidPlugin druidPlugin;
		ActiveRecordPlugin arp;
		for (Database bean : databases) {
			if (StrKit.equals("MongoDB", bean.getType())) {
			} else {
				druidPlugin = new DruidPlugin(bean.getUrl(), bean.getUser(), bean.getPassword());
				if (!"sqlite".equalsIgnoreCase(bean.getType()))
					druidPlugin.set(bean.getInitialSize(), bean.getMinIdle(), bean.getMaxActive());
				arp = new ActiveRecordPlugin(bean.getName(), druidPlugin);
				arp.setShowSql(bean.isShowSql());
				arp.setTransactionLevel(Connection.TRANSACTION_READ_COMMITTED);
				arp.getEngine().setToClassPathSourceFactory();
				if (!StrKit.isBlank(bean.getSqlTemplate())) {
					arp.addSqlTemplate(bean.getSqlTemplate());
				}

				if (bean.getMappingClassList() != null && bean.getMappingClassList().size() > 0) {
					for (String mappingClass : bean.getMappingClassList()) {
						ReflectUtil.on(mappingClass).call("mapping", arp);
					}
				}

				if ("oracle".equalsIgnoreCase(bean.getType())) {
					druidPlugin.setDriverClass(bean.getDriverClass());
					arp.setDialect(new OracleDialect());

				} else if ("mysql".equalsIgnoreCase(bean.getType())) {
					arp.setDialect(new MysqlDialect());
				} else if ("sqlserver".equalsIgnoreCase(bean.getType())) {
					arp.setDialect(new SqlServerDialect());
				} else if ("sqlite".equalsIgnoreCase(bean.getType())) {
					druidPlugin.setDriverClass(bean.getDriverClass());
					arp.setDialect(new Sqlite3Dialect());
				} else if ("postgresql".equalsIgnoreCase(bean.getType())) {
					druidPlugin.setDriverClass(bean.getDriverClass());
					arp.setDialect(new PostgreSqlDialect());
				}
				// arp.setContainerFactory(new CaseInsensitiveContainerFactory(true));//false
				// 是大写, true是小写, 不写是区分大小写
				druidPlugin.start();
				arp.start();
			}
		}

	}

	@SuppressWarnings("unchecked")
	private static List<Database> parseXmlToList() {
		List<Database> lists = new LinkedList<Database>();
		try {
			SAXReader reader = new SAXReader();
			reader.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
			Document document = reader.read(DbUtil.class.getResourceAsStream("/springboot.xml"));
			Element root = document.getRootElement();
			List<Element> elements = root.elements();

			List<Element> mappingClass;
			Database bean;
			for (Element element : elements) {
				bean = new Database();
				bean.setName(element.elementText("name"));
				bean.setType(element.elementText("type"));
				bean.setUser(element.elementText("user"));
				bean.setPassword(element.elementText("password"));
				bean.setUrl(element.elementText("url"));

				if (element.element("mappingClass") == null) {
					continue;
				}

				if (element.element("mappingClass").elements() != null) {
					mappingClass = element.element("mappingClass").elements();
					if (mappingClass != null && mappingClass.size() > 0) {
						List<String> eleList = new LinkedList<String>();
						for (Element ele : mappingClass) {
							eleList.add(ele.getText());
						}
						bean.setMappingClassList(eleList);
					}
				}
				if (!StrKit.isBlank(element.elementText("port"))) {
					bean.setPort(Integer.parseInt(element.elementText("port")));
				}
				if (!StrKit.isBlank(element.elementText("initialSize"))) {
					bean.setInitialSize(Integer.parseInt(element.elementText("initialSize")));
				}
				if (!StrKit.isBlank(element.elementText("minIdle"))) {
					bean.setMinIdle(Integer.parseInt(element.elementText("minIdle")));
				}
				if (!StrKit.isBlank(element.elementText("maxActive"))) {
					bean.setMaxActive(Integer.parseInt(element.elementText("maxActive")));
				}
				if (!StrKit.isBlank(element.elementText("showSql"))) {
					bean.setShowSql(Boolean.parseBoolean(element.elementText("showSql")));
				}
				if (!StrKit.isBlank(element.elementText("driverClass"))) {
					bean.setDriverClass(element.elementText("driverClass"));
				}
				lists.add(bean);
			}
		} catch (DocumentException e) {
			e.printStackTrace();
		} catch (SecurityException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return lists;
	}

}
